﻿using System;

namespace QNUnit.Core.Loggers
{
    public class Teamcity : ILogger
    {
        #region Fields

        private readonly string _suiteName;

        #endregion

        #region Constructors

        public Teamcity(string suiteName)
        {
            _suiteName = suiteName;
        }

        #endregion

        #region Public

        public void StartTestSuite()
        {
            PrintLine("##teamcity[testSuiteStarted name='{0}']", _suiteName);
        }

        public void EndTestSuite()
        {
            PrintLine("##teamcity[testSuiteFinished name='{0}']", _suiteName);
        }

        public void StartTestFile(string testName, string fileName)
        {
            PrintLine("##teamcity[testStdOut name='{0}' out='Started testing QUnit file {1}']", testName, fileName);
        }

        public void EndTestFile(string testName, string fileName)
        {
            PrintLine("##teamcity[testStdOut name='{0}' out='Finished testing QUnit file {1}']", testName, fileName);
        }

        public void StartSubTest(string testName, int testIndex)
        {
            PrintLine("##teamcity[testStarted name='{0}, Test #{1}']", testName, testIndex.ToString());
        }

        public void EndSubTest(string testName, int testIndex)
        {
            PrintLine("##teamcity[testFinished name='{0}, Test #{1}']", testName, testIndex.ToString());
        }

        public void PassSubTest(string testName, int testIndex, string message)
        {
            PrintLine("##teamcity[testStdOut name='{0}, Test #{1}' out='{2}']", testName, testIndex.ToString(), message);
        }

        public void FailShortSubTest(string testName, int testIndex, string message)
        {
            PrintLine("##teamcity[testFailed name='{0}, Test #{1}' details='{2}']", testName, testIndex.ToString(), message);
        }

        public void FailSubTest(string testName, int testIndex, string message, string expected, string actual)
        {
            PrintLine("##teamcity[testFailed type='comparisonFailure' name='{0}, Test #{1}' details='{2}' expected='{3}' actual='{4}']", testName, testIndex.ToString(), message, expected, actual);
        }

        #endregion

        #region Private

        private static void PrintLine(string formatString, params string[] args)
        {
            var escapedArgs = new string[args.Length];

            for (var index = 0; index < args.Length; index++)
                escapedArgs[index] = EscapeCharacters(args[index]);

            Console.WriteLine(formatString, escapedArgs);
        }

        private static string EscapeCharacters(string input)
        {
            return input.Replace("'", "|'");
        }

        #endregion
    }
}
